package com.meida.module.arc.provider.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.meida.common.base.constants.CommonConstants;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.DateUtils;
import com.meida.module.admin.client.entity.BaseUser;
import com.meida.module.arc.client.entity.ArcInfo;
import com.meida.module.arc.client.entity.ArcInfoComment;
import com.meida.module.arc.provider.mapper.ArcInfoCommentMapper;
import com.meida.module.arc.provider.service.ArcInfoCommentService;
import com.meida.module.arc.provider.service.ArcInfoService;
import com.meida.module.arc.provider.service.ArcUseRemindService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 档案评论接口实现类
 *
 * @author flyme
 * @date 2023-07-24
 */
@Service
@DS("sharding")
@Transactional(rollbackFor = Exception.class)
public class ArcInfoCommentServiceImpl extends BaseServiceImpl<ArcInfoCommentMapper, ArcInfoComment> implements ArcInfoCommentService {

    @Resource
    ArcInfoService arcInfoService;
    @Autowired
    ArcUseRemindService arcUseRemindService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcInfoComment aic, EntityMap extra) {

        ArcInfo arcInfo = arcInfoService.getArcInfo(aic.getArcInfoId(), aic.getCategoryId());

        ApiAssert.isNotEmpty("档案不存在", arcInfo);
        //评论ID
        Long replyCommentId = aic.getReplyCommentId();
        Long userId = OpenHelper.getUserId();
        aic.setDzNum(0);
        aic.setReplyState(CommonConstants.ENABLED);
        aic.setReplyUserId(userId);
        if (FlymeUtils.isEmpty(replyCommentId)) {
            //aic.setReplyToUserId(Long.valueOf(  arcInfo.getCreateBy()));
        } else {
            ArcInfoComment parent = getById(replyCommentId);
            aic.setReplyToUserId(parent.getReplyUserId());
        }
        return ResultBody.ok();
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcInfoComment> cq, ArcInfoComment aic, EntityMap requestMap) {
        ApiAssert.isNotEmpty("arcInfoId不能为空", aic);
        initCriteriaQuery(cq, aic);
        return ResultBody.ok();
    }

    @Override
    public List<EntityMap> afterPageList(CriteriaQuery<ArcInfoComment> cq, List<EntityMap> data, ResultBody resultBody) {
        getChildComment(data, 2);
        return data;
    }

    /**
     * 设置CriteriaQuery
     *
     * @param cq
     * @param aic
     */
    private void initCriteriaQuery(CriteriaQuery cq, ArcInfoComment aic) {
        Long userId = OpenHelper.getUserId();
        cq.select(ArcInfoComment.class, "commentId", "arcInfoId", "dzNum", "replyContent", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.userNo replyUserNo", "replyUser.avatar replyAvatar");
        cq.isNull("aic.replyCommentId");

        cq.eq(ArcInfoComment.class, "arcInfoId", aic.getArcInfoId());
        cq.eq(ArcInfoComment.class, "categoryId", aic.getCategoryId());
        cq.eq(ArcInfoComment.class, "qzId", aic.getQzId());
        cq.eq(ArcInfoComment.class, "replyState", CommonConstants.ENABLED);
        cq.createJoin(BaseUser.class).setJoinAlias("replyUser").setMainField("replyUserId");
        cq.orderByDesc("aic.createTime");

    }


    @Override
    public ResultBody afterAdd(CriteriaSave cs, ArcInfoComment comment, EntityMap extra) {
        //消息记录
        if (comment.getReplyToUserId() != null) {
            this.arcUseRemindService.createRemid(4, "回复了你的评论", comment.getQzId(), comment.getReplyToUserId(), comment.getReplyUserId(), comment.getArcInfoId());
        }
        Long count = this.allCountByArcInfoId(comment.getArcInfoId());
        arcInfoService.updateCommentCount(comment.getCategoryId(), comment.getArcInfoId(), count);

        return ResultBody.msg("评论成功");
    }

    @Override

    public ResultBody beforeDelete(CriteriaDelete<ArcInfoComment> cd) {

        Long[] ids = cd.getIds();
        ApiAssert.isNotEmpty("删除对象不能为空", ids);
        List<ArcInfoComment> list = this.listByIds(Arrays.asList(ids));
        for (ArcInfoComment comment : list) {
            Long count = this.allCountByArcInfoId(comment.getArcInfoId());
            arcInfoService.updateCommentCount(comment.getCategoryId(), comment.getArcInfoId(), count - 1);
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterDelete(CriteriaDelete cd, Long[] ids) {
        return ResultBody.ok();
    }


    @Override
    public List<EntityMap> listByContentIdAndSize(Long arcInfoId, Integer showType, Integer size) {
        ApiAssert.isNotEmpty("arcInfoId不能为空", arcInfoId);
        CriteriaQuery cq = new CriteriaQuery(ArcInfoComment.class);
        //initCriteriaQuery(cq, arcInfoId);
        List<EntityMap> resultList = selectEntityMap(cq);
        getChildComment(resultList, showType);
        return resultList;
    }

    /**
     * 递归查询子评论
     *
     * @param parentComments
     * @return
     */
    @Override
    public List<EntityMap> getChildComment(List<EntityMap> parentComments, Integer showType) {
        if (FlymeUtils.isEmpty(parentComments)) {
            return null;
        }
        for (EntityMap parentComment : parentComments) {
            Long commentId = parentComment.getLong("commentId");
            Date createTime = parentComment.get("createTime");
            //格式化显示日期
            String showTime = DateUtils.formatFromTodayCn(createTime);
            parentComment.put("showTime", showTime);
            List<EntityMap> sonComments = selectByReplyCommentId(commentId, showType);
            List<EntityMap> child = getChildComment(sonComments, showType);
            child = FlymeUtils.isEmpty(child) ? new ArrayList<>() : child;
            parentComment.put("child", child);
        }
        return parentComments;
    }

    /**
     * 根据评论ID查询评论内容
     *
     * @param replyCommentId
     * @return
     */
    private List<EntityMap> selectByReplyCommentId(Long replyCommentId, Integer showType) {
        Long userId = OpenHelper.getUserId();
        CriteriaQuery cq = new CriteriaQuery(ArcInfoComment.class);
        cq.select(ArcInfoComment.class, "commentId", "arcInfoId", "replyContent", "dzNum", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.avatar replyAvatar");
        //微信形式(张三回复李四),要查询给回复给谁
        cq.addSelect("toUser.userId toUserId", "toUser.nickName toNickName", "toUser.userName toUserName", "toUser.avatar toUserAvatar");
        cq.createJoin(BaseUser.class).setJoinAlias("toUser").setMainField("replyToUserId");
        cq.eq(ArcInfoComment.class, "replyCommentId", replyCommentId);
        cq.eq(ArcInfoComment.class, "replyState", CommonConstants.ENABLED);
        cq.createJoin(BaseUser.class).setJoinAlias("replyUser").setMainField("replyUserId");
        cq.orderByDesc("aic.createTime");
        return selectEntityMap(cq);
    }

    /**
     * 统计回复数量
     *
     * @param arcInfoId
     * @return
     */
    @Override
    public Long countByContentId(Long arcInfoId) {
        CriteriaQuery cq = new CriteriaQuery(ArcInfoComment.class);
        cq.eq(true, "arcInfoId", arcInfoId);
        cq.eq(true, "replyState", CommonConstants.ENABLED);
        return count(cq);
    }

    public Long allCountByArcInfoId(Long arcInfoId) {
        CriteriaQuery cq = new CriteriaQuery(ArcInfoComment.class);
        cq.eq(true, "arcInfoId", arcInfoId);
        return count(cq);
    }

    @Override
    public ResultBody getReplyPageList(Map params) {
        Long userId = OpenHelper.getUserId();
        CriteriaQuery<ArcInfoComment> cq = new CriteriaQuery(params, ArcInfoComment.class);
        cq.select(ArcInfoComment.class, "commentId", "arcInfoId", "replyCommentId", "replyContent", "dzNum", "replyImages", "createTime");
        cq.addSelect("replyUser.userId replyUserId", "replyUser.nickName replyNickName", "replyUser.userName replyUserName", "replyUser.avatar replyAvatar");
        cq.eq("replyToUserId", userId);
        cq.createJoin(BaseUser.class).setJoinAlias("replyUser").setMainField("replyUserId");
        return basePageList(cq);
    }

    @Override
    public Boolean updateDzNum(Long commentId, Integer num) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.setSql(true, "dzNum=dzNum+" + num);
        cu.ge("dzNum", 0);
        cu.eq(true, "commentId", commentId);
        return update(cu);
    }
}
